package com.lt.flashcard.view;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;
import org.zkoss.util.resource.Labels;
import org.zkoss.xel.fn.StringFns;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.metainfo.ComponentInfo;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Include;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Textbox;

import com.lt.flashcard.Utility;
import com.lt.flashcard.model.entity.Flashcard;
import com.lt.flashcard.model.entity.FlashcardSet;
import com.lt.flashcard.model.entity.Notification;
import com.lt.flashcard.model.entity.User;
import com.lt.flashcard.model.entity.Vote;
import com.lt.flashcard.model.service.AAService;
import com.lt.flashcard.model.service.FlashcardSetService;
import com.lt.flashcard.model.service.NotificationService;
import com.lt.flashcard.model.service.Repository;
import com.lt.flashcard.model.service.VoteService;

public class WordlistDetailMainCtrl extends SelectorComposer<Component> {
	
	private static final Logger log = Logger.getLogger(WordlistDetailMainCtrl.class);

	private static final long serialVersionUID = 1L;
	/**
	 * Store current flashcard set
	 */
	private FlashcardSet flashcardset = null;
	
	@Wire
	Include list_flashcards;
	@Wire
	Textbox rating;
	@Wire
	Label sao_diem;
	@Wire
	Label voteResult;
	@Wire
	Label voteTotal;
	@Wire
	Textbox g_name_set;
	@Wire
	Textbox description_set;
	@Wire
	Textbox tags_set;
    @Wire
	Listbox g_list_set;
	
	private User user;
	private boolean isAllowedEdit = false;
	private List<FlashcardSet> flashcardsets = new ArrayList<FlashcardSet>();
	
	private Vote myrate = null; //My rating for this flashcard set
	
	@Wire
	Include grid_flashcards;
	
	@Override
	public ComponentInfo doBeforeCompose(Page page, Component parent, ComponentInfo compInfo) {
		FlashcardSetService srv = Repository.getInstance().getFlashcardSetService();
		String strId = Executions.getCurrent().getParameter("id");
		try {
			int id = Integer.parseInt(strId);
			if(id > 0) {
				flashcardset = srv.findByID(new Long(id));
			}
		}
		catch (Exception e) { }
		
		if(flashcardset == null) {
			Utility.display404(true);
			return null;
		}
		
		user = Utility.getUser();
		
		if(!isOwner()) {
			//redirect in case this is admin product
			if(flashcardset.getAdmin() == FlashcardSet.ADMIN_BUY) {
				String tid = flashcardset.getOriginalflashcardsetCache(); //the id of original product
				String url = Utility.generateUrl("store_detail", tid, flashcardset.getName());
				Utility.redirect(Utility.removeContextPath(url), false);
				return null;
			}
			else if(flashcardset.getAdmin() == FlashcardSet.ADMIN_YES) {
				String url = Utility.generateUrl("store_detail", flashcardset.getId(), flashcardset.getName());
				Utility.redirect(Utility.removeContextPath(url), false);
				return null;
			}
		}
		
		VoteService vsrv = Repository.getInstance().getVoteService();
		if(user != null) {
            myrate = vsrv.getVote(user.getId(), flashcardset.getId(), 0);
        }
		
		srv.updateViewCount(flashcardset);
		if(!isOwner() && Utility.isLogin()) {
			flashcardsets = srv.getFlashcardsetsOfCurrUser(user, true);
		}
		
		AAService asrv = Repository.getInstance().getAAService();
		isAllowedEdit = asrv.checkEdit(user, flashcardset);
		
		Utility.addOgTag(page, 
				Utility.generateTitle("flashcardset", flashcardset), 
				Utility.generateDescription("flashcardset", flashcardset),
				Utility.loadImageFromGridFS(flashcardset.getImage(), Utility.DEF_FLASHCARDSET));
		
		return super.doBeforeCompose(page, parent, compInfo);
	}
	
	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		String so = String.valueOf(flashcardset.getFlashcards().size());
		grid_flashcards.setVisible(false);
	};
	
	//--> setters and getters
	public FlashcardSet getFlashcardset() {
		return flashcardset;
	}

	public void setFlashcardset(FlashcardSet flashcardset) {
		this.flashcardset = flashcardset;
	}

	public List<FlashcardSet> getRelatedList() {
		FlashcardSetService srv = Repository.getInstance().getFlashcardSetService();
		return srv.getRelatedFlashcardSet(flashcardset);
	}
		
	 public List<FlashcardSet> getOriginalFlashcardSet() {
		 FlashcardSetService srv = Repository.getInstance().getFlashcardSetService();
		 return srv.getOriginalFlashcardSet(flashcardset);
	 }

	/**
	 * @return the user
	 */
	public User getUser() {
		return user;
	}

	/**
	 * @param user the user to set
	 */
	public void setUser(User user) {
		this.user = user;
	}

	/**
	 * @return the isAllowedEdit
	 */
	public boolean isAllowedEdit() {
		return isAllowedEdit;
	}

	/**
	 * @param isAllowedEdit the isAllowedEdit to set
	 */
	public void setAllowedEdit(boolean isAllowedEdit) {
		this.isAllowedEdit = isAllowedEdit;
	}

	@Listen("onChange=#rating")
	public void saveRating() {
		if(!Utility.isLogin()) {
			Clients.evalJavaScript("showNotice('', 'Bạn phải đăng nhập để đánh giá', { })");
			return;
		}
		FlashcardSetService fsrv = Repository.getInstance()
				.getFlashcardSetService();
		fsrv.updateRating(flashcardset, new Integer(rating.getValue()));
		DecimalFormat df = new DecimalFormat("0.0");
		String voteResult = df.format(flashcardset.getVoteResult());
		this.sao_diem.setValue(voteResult);
		this.voteResult.setValue(voteResult);
		this.voteTotal.setValue(String.valueOf(flashcardset.getVoteTotal()));
		Clients.evalJavaScript("showNotice('', '"
				+ Labels.getLabel("wordlist_detail.rating.updatesuccess")
				+ "')");

		NotificationService nsrv = Repository.getInstance().getNotificationService();
		nsrv.addNotificationRating(user, flashcardset.getAuthor(), flashcardset, new Integer(rating.getValue()));
	}
	
	 protected void listOrGrid(boolean isList) {
	    if(isList){
	    	list_flashcards.setVisible(true);
	    	grid_flashcards.setVisible(false);
	    }else{
	    	list_flashcards.setVisible(false);
	    	grid_flashcards.setVisible(true);
	    	Clients.evalJavaScript("$(':checkbox').uniform();");
	    }
    }
	 /**
	  * do share and save notification
	  */
	 @Listen("onClick=#share")
	 public void doShare(){
		 //TO DO share
		 
		 //save notificaiton
		 NotificationService nsrv = Repository.getInstance().getNotificationService();
		 Notification notification = new Notification();
		 notification.setSourceuid(user.getId());
		 notification.setSourceuname(user.getUsername());
		 notification.setTargetuid(flashcardset.getAuthor().getId());
		 notification.setRelatedid(flashcardset.getId());
		 notification.setRelatedname(flashcardset.getName());
		 notification.setType(Notification.TYPE_SHARE);
		 nsrv.saveNotification(notification);
	}
	 
	 @Listen("onClick=#btnDelete")
	 public void deleteFlashcardSet() {
		 if(isAllowedEdit()) {
			 FlashcardSetService srv = Repository.getInstance().getFlashcardSetService();
			 if(log.isInfoEnabled()) {
                log.info(String.format("User %s delete flascardset %s", user.getId(), flashcardset.getId()));
            }
			 srv.delete(flashcardset);
			 //Messagebox.show("Finish");
			 Utility.redirect("dashboard.zul", true);
		 }
	 }
	 
	public boolean isOwner() {
			FlashcardSetService fcsrv = Repository.getInstance().getFlashcardSetService();
			return fcsrv.checkOwnFlashcardSet(getUser(), flashcardset);
	}

	public List<FlashcardSet> getFlashcardsets() {
		return flashcardsets;
	}

	public void setFlashcardsets(List<FlashcardSet> flashcardsets) {
		this.flashcardsets = flashcardsets;
	}
	
	/**
	 * Copy all flashcards to existing flashcardset
	 */
  	@Listen("onClick=#g_save_flashcards_into_set")
  	public void saveIntoFlashcardSet() {
  		FlashcardSetService fsSrv = Repository.getInstance().getFlashcardSetService();
  		if(user.getCurrentblankflashcard() == 0){
  			Clients.evalJavaScript("showNotice('','Bạn đã hết flashcard trắng, vui lòng mua thêm để sử dụng!',{ yes: callback, btnYes: 'Mua thêm' })");
			return;
  		}
		Listitem sl = g_list_set.getSelectedItem();
		FlashcardSet setSelected = (FlashcardSet) (sl == null ? null : sl.getValue());
		if(setSelected == null){
			Clients.evalJavaScript("showNotice('','Vui lòng chọn một flashcard set!')");
			return;
		}
		List<String> dupplicated = new ArrayList<String>();//Dupplicated term
		int success = 0;
		for (Flashcard fc : flashcardset.getFlashcards()) {
			if(setSelected.isTermExist(fc.getTerm())) {
				dupplicated.add(fc.getTerm());
      			continue;
      		}
			
			Flashcard insertFlashcard = fc.clone();
    		setSelected.addFlashcard(insertFlashcard);
    		success +=1;
		}
		if(success > 0) {
			//TODO Check blank flashcard
			if(success > user.getCurrentblankflashcard()){
				Clients.evalJavaScript("showNotice('','Số lượng flashcard trắng của bạn không đủ, vui lòng mua thêm để sử dụng!',{ yes: function(){self.location='store/flashcard-trang';}, btnYes: 'Mua thêm' })");
				return;
			}
			fsSrv.save(setSelected);
		}
		String fail = StringFns.join(dupplicated.toArray(), ", ");
		if(fail.length() > 0) {
			Clients.evalJavaScript("showNotice('', 'Hoàn tất! Các card sau bị trùng: " + fail + "')");
		}
		else if(success > 0) {
			Clients.evalJavaScript("showNotice('', 'Hoàn tất!')");
		}
  	}
  	
  	@Listen("onClick=#g_create_set")
  	public void createAndSaveFlashcardSet() {
  		FlashcardSetService fsSrv = Repository.getInstance().getFlashcardSetService();
  		if(Utility.isEmptyString(g_name_set.getValue())){
  			Clients.evalJavaScript("showNotice('','Vui lòng nhập tên flashcard set');");
  			return;
  		}
  		if(user.getCurrentblankflashcard() == 0){
  			Clients.evalJavaScript("showNotice('','Bạn đã hết flashcard trắng, vui lòng mua thêm để sử dụng!',{ yes: function(){self.location='store/flashcard-trang';}, btnYes: 'Mua thêm' })");
			return;
  		}
  		else if(user.getCurrentblankflashcard() < flashcardset.getTotalflashcards()){
  			Clients.evalJavaScript("showNotice('','Số lượng flashcard trắng của bạn không đủ, vui lòng mua thêm để sử dụng!',{ yes: function(){self.location='store/flashcard-trang';}, btnYes: 'Mua thêm' })");
			return;
  		}
		FlashcardSet newSet = new FlashcardSet();
  		newSet.setName(g_name_set.getValue());
  		newSet.setAuthor(user);
  		newSet.setDescription(description_set.getValue());
  		if(!Utility.isEmptyString(tags_set.getValue())) {
  			newSet.addTags(Arrays.asList(tags_set.getValue().split(",")));
  		}
  		fsSrv.copyFlashcards(flashcardset, newSet);
  		fsSrv.save(newSet);

		Executions.sendRedirect("/flashcard.zul?task=edit&id=" + newSet.getId().toString());
  	}

	public Vote getMyrate() {
		return myrate;
	}

	public void setMyrate(Vote myrate) {
		this.myrate = myrate;
	}
}
